<?php
/**
 *@file comment.php
 *@author Zhe.Zhou(zhouzhe@haibao.com)
 *@date 2015-7-29 下午4:21:02
 *@brief  
 */
namespace haibao\app\data;

use haibao\cms\web\ajax\Feature;
class Comment extends BaseMysql{
    
    private static $tmpArr = array();
    
	public function __construct(){
		parent::__construct('\haibao\app\model\data\Comments');
	}
	
	public function getCommentById($commentId){
	    return $this->getOneById($commentId);
	}
	
	public function getNewCommentList($articleId, $commentId = null){
	    $commentList = array();
	    $cache = new \haibao\app\cache\Comment();
	    if($commentId == null){
	        $commentList = $cache->getCommentList($articleId);
	    }
	    if(!$commentList){
	       $commentIdArr = $this->getMainCommentIdArr($articleId, $commentId);
	       $commentList = $this->getCommentData($articleId, $commentIdArr);
	       if($commentId == null){
	           $cache->setCommentList($articleId, $commentList);
	       }
	    }
	    return $commentList;
	}
	
	/**
	 * 根据文章Id和主评论Id获取评论数据
	 * @param int $articleId
	 */
	public function getCommentData($articleId, array $commentIdArr){
	    if(!$commentIdArr){
	        return array();
	    }
        if($commentTree = $this->getCommentTree($articleId, $commentIdArr)){
            foreach($commentTree as $key=>$value){
                // 过滤掉已经删除的评论
                if($value['status'] == \haibao\app\model\data\Comments::STATUS_DEL){
                    unset($commentTree[$key]);
                    continue;
                }
                self::$tmpArr = array();
                if(isset($value['children'])){
                    $children = $this->moveArray($value['children']);
                    $children = $this->arraySort($children, 'commentId', SORT_ASC);
                    $childrenArr = array();
                    foreach($children as $k=>$v){
                        if($v['status'] != \haibao\app\model\data\Comments::STATUS_DEL){
                            unset($v['status']);
                            array_push($childrenArr, $v);
                        }
                    }
                    $commentTree[$key]['children'] = $childrenArr;
                }
                unset($commentTree[$key]['status']);
            }
        }
	    return $commentTree;
	}
	
	public function updateArticleCommentNum($commentId,$type){
        $tag = $type ? '-' : '+';
        $sql = "update ArticleProperty set CommentNum = `CommentNum`".$tag."1 where ArticleId = (select ObjectId from `Comment` where Id=%s)";
        $this->query($sql,array($commentId));
	}
	
	public function getCommentCountByArticleId($articleId){
	    $sql = 'select count(*) as num from `Comment` where ObjectId=%s and Status='.\haibao\app\model\data\Comments::STATUS_OK;
	    $this->setReadPerformance(true);
	    $result = $this->query($sql, array($articleId));
	    
	    $count = 0;
	    if($ret = $result->fetch_assoc()){
	        $count = $ret['num'];
	    }
	    return $count;
	}
	
	/**
	 * 更新评论数量
	 */
	public function updateCommentCount($commentId){
	    if(is_array($commentId)){
	        foreach($commentId as $key=>$val){
	            $sql = 'update ArticleProperty set CommentNum = (select count(*) from `Comment` where ObjectId=(select ObjectId from `Comment` where Id=%s) and Status=%s) where ArticleId=(select ObjectId from `Comment` where Id=%s)';
	            $this->query($sql, array(
	                $val, \haibao\app\model\data\Comments::STATUS_OK, $val
	            ));
	        }
	    }else{
	        $sql = 'update ArticleProperty set CommentNum = (select count(*) from `Comment` where ObjectId=(select ObjectId from `Comment` where Id=%s) and Status=%s) where ArticleId=(select ObjectId from `Comment` where Id=%s)';
	        $this->query($sql, array(
	            $commentId, \haibao\app\model\data\Comments::STATUS_OK, $commentId
	        ));
	    }
	    
	}
	
	/**
	 * @param \haibao\app\model\data\Comments $model
	 */
	public function saveComment($model){
	    $this->beginTranscation();
	    try {
	       $this->add($model);
	       
	       // 父级评论用户收到一条回复
	       if($model->ReplyCommentId){
	           $parent = $this->getCommentById($model->ReplyCommentId);
	       }
	       if(isset($parent) && $model->UserId != $parent->UserId){
	           $m = new \haibao\app\model\data\CommentReply();
	           $m->ArticleId = $parent->ObjectId;
	           $m->CommentId = $model->Id;
	           $m->MainCommentId = !empty($parent->MainCommentId) ? $parent->MainCommentId : $parent->Id;
	           $m->FromUserId = $model->UserId;
	           $m->FromNickname = $model->Nickname;
	           $m->ToUserId = $parent->UserId;
	           $m->ToNickname = $parent->Nickname;
	           $m->ReceiveUserId = $parent->UserId;
	           $m->ReceiveNickname = $parent->Nickname;
	           $m->ReplyContent = $model->Content;
	           $m->RepliedContent = $parent->Content;
	           if(!empty($parent->MainCommentId)){
	               $main = $this->getCommentById($parent->MainCommentId);
	               $m->MainContent = $main->Content;
	           }else{
    	           $m->MainContent = $parent->Content;
	           }
	           $m->ReplyTime = $model->AddTime;
	           $m->Status = \haibao\app\model\data\CommentReply::STATUS_NO;
	           $data = new \haibao\app\data\CommentReply();
	           $data->saveCommentReply($m);
	           
    	       // 主评论用户收到一条回复
    	       if($parent->MainCommentId){
    	           if(!isset($main)){
    	               $main = $this->getCommentById($parent->MainCommentId);
    	           }
    	           if($model->UserId != $main->UserId && $parent->UserId!= $main->UserId){
    	               $m->ReceiveUserId = $main->UserId;
    	               $m->ReceiveNickname = $main->Nickname;
    	               $data->saveCommentReply($m);
    	           }
    	       }
	       }
	       
	       $this->updateCommentCount($model->Id);
	       $this->deleteCommentCache($model->ObjectId);
       } catch (\Exception $e) {
           $this->rollback();
           throw $e;
       }
       $this->endTranscation();
	}
	
	/**
	 * 删除评论
	 */
	public function deleteComment($userId, $commentId){
	    $this->beginTranscation();
	    try {
	        $comment = $this->getCommentById($commentId);
	        if(!$comment || $comment->UserId != $userId){
	            return false;
	        }
	        $data = new \haibao\app\data\CommentReply();
	        // 连带删除子评论的做法!!!
	        if(empty($comment->MainCommentId) && empty($comment->ReplyCommentId)){
    	        $commentIdArr = (array)$this->getChildCommentIdArr($comment->ObjectId, $commentId);
    	        array_unshift($commentIdArr, $commentId);
    	        $paramArr = $commentIdArr = array_filter(array_unique($commentIdArr));
    	        array_unshift($paramArr, \haibao\app\model\data\Comments::STATUS_DEL);
    	        
    	        $str = preg_replace('/(\d+)/', '%s', implode(',', $commentIdArr));
        	    $this->query('update `Comment` set Status=%s where Id in ('.$str.')', $paramArr);
        	    
        	    // 删除所有评论回复消息通知
        	    $data->deleteReplyByCommentId($comment->MainCommentId);
	        }else{
    	        // 只删除本评论的做法!!!
    	        $this->query('update `Comment` set Status=%s where Id=%s and UserId=%s', array(
    	            \haibao\app\model\data\Comments::STATUS_DEL, $commentId, $userId
    	        ));
    	        // 仅删除本评论消息通知
    	        $data->deleteReplyByCommentId($comment->Id);
	        }
    	    $this->deleteCommentCache($comment->ObjectId);
	    } catch (\Exception $e) {
	        $this->rollback();
	        throw $e;
	    }
	    $this->endTranscation();
	}

	/**
	 * 根据用户ID获取用户头像地址
	 */
	public function getAvatarById($userId){
	    $avatarUrl = \haibao\classlibrary\app\Config::getConfig(\haibao\classlibrary\app\Config::CLASSLIBRARY_CONFIG_HOST_BBS).'/uc_server/data/avatar/'.\haibao\app\business\Authuser::getAvatarById($userId,'big');
	    if(strpos(file_get_contents($avatarUrl), '<!DOCTYPE HTML>') !== false){
	        $avatarUrl = '';
	    }
	    return $avatarUrl;
	}
	
	/**
	 * 根据父级Id获取所有子集评论Id
	 */
	private function getChildCommentIdArr($articleId, $commentId){
	    $commentTree = $this->getCommentTree($articleId, array($commentId));
	    $childTree = $this->findTreeNode($commentTree, $commentId);
	    return $this->findCommentId($childTree);
	}
	
	private function findCommentId($childTree){
	    if(!$childTree){
	        return false;
	    }
	    static $commentIdArr = array();
	    foreach($childTree as $key=>$comment){
	        array_push($commentIdArr, $comment['commentId']);
	        if(isset($comment['children'])){
	            $this->findCommentId($comment['children']);
	        }
	    }
	    return $commentIdArr;
	}
	
	private function findTreeNode(array $commentTree, $node){
	    if(!$commentTree){
	        return false;
	    }
	    
	    static $treeNode = array();
	    foreach($commentTree as $key=>$comment){
	        if($comment['commentId'] == $node){
	            $treeNode = array_key_exists('children', $comment) ? $comment['children'] : array();
	            break;
	        }
	        if(isset($comment['children'])){
	            $this->findTreeNode($comment['children'], $node);
	        }
	    }
	    return $treeNode;
	}
	
	/**
	 * 查询主评论Id
	 */
	private function getMainCommentIdArr($articleId, $commentId){
	    $sql = 'select Id from Comment where ObjectId=%s and MainCommentId is null';
	    if($commentId){
	        $sql .= ' and Id<'.intval($commentId);
	    }
	    $sql .= ' order by Id desc limit 20';
	    $result = $this->query($sql, array($articleId));
	    $commentIdArr = array();
	    while($result->fetch_assoc()){
	        array_push($commentIdArr, $result->getData('Id'));
	    }
	    return $commentIdArr;
	}
	
	/**
	 * @param string $articleId 文章Id
	 * @param array $commentIdArr 主评论Id
	 */
	private function getCommentTree($articleId, $commentIdArr){
	    if($commentIdArr){
            $idStr = implode(',', $commentIdArr);
            $sql = 'select * from `Comment` where ObjectId=%s and (Id in('.$idStr.') or MainCommentId in('.$idStr.')) order by Id desc';
	    }
	    $result = $this->query($sql, array(
	        $articleId
	    ));
	    $commentArr = array();
	    while ($row = $result->fetch_assoc()){
	        $arr = array();
	        $arr['commentId'] = $row['Id'];
	        $arr['replyCommentId'] = $row['ReplyCommentId'];
	        $arr['toUserId'] = $row['ReplyUserId'];
	        $arr['toUsername'] = '';
	        $arr['content'] = stripcslashes(json_decode($row['Content'], true));
	        $arr['fromUserId'] = $row['UserId'];
	        $arr['fromUsername'] = $row['Nickname'];
	        $arr['fromAvatar'] = '';
	        $arr['addTime'] = $row['AddTime'];
	        $arr['status'] = $row['Status'];
	        $commentArr[$result->getData('Id')] = $arr;
	    }
	    
	    $commentTree = array();
	    if($commentArr){
	        foreach($commentArr as $key=>$reply){
	            if(isset($commentArr[$reply['replyCommentId']])){
	                $commentArr[$reply['commentId']]['toUsername'] = $commentArr[$reply['replyCommentId']]['fromUsername'];
	                $commentArr[$reply['commentId']]['fromAvatar'] = $this->getAvatarById($reply['fromUserId']);
	                $commentArr[$reply['replyCommentId']]['children'][$reply['commentId']] = &$commentArr[$reply['commentId']];
	            }else{
	                $commentTree[$reply['commentId']] = &$commentArr[$reply['commentId']];
	                $commentTree[$reply['commentId']]['fromAvatar'] = $this->getAvatarById($reply['fromUserId']);
	            }
	        }
	    }
	    return $commentTree;
	}
	
	private function moveArray($data){
	    if(!$data){
	        return false;
	    }
        foreach($data as $key=>$item){
            if(isset($item['children'])){
                $arr = $item;
                unset($arr['children']);
                $arr['isLeaf'] = 0;
                array_push(self::$tmpArr, $arr);
                self::$tmpArr = $this->moveArray($item['children']);
            }else{
                array_push(self::$tmpArr, $item);
            }
        }
        return self::$tmpArr;
	}
	
	public function deleteCommentCache($articleId){
	    $cache = new \haibao\app\cache\Comment();
	    $cache->deleteCommentList($articleId);
	}
	
	public function updateByCommentId($id, $arrSet){
	    if(is_array($id)){
	        foreach($id as $key=>$val){
	            $this->updateById($val, $arrSet);
	        }
	    }else{
	        $this->updateById($id, $arrSet);
	    }
	}
	
	/**
	 * 二维数组按照某以键值排序
	 * arraySort($array, $keys, $type = SORT_DESC)
	 */
	private function arraySort($array, $keys, $type = SORT_DESC) {
	    $keysValue = $newArray = array();
	    foreach ($array as $k => $v) {
	        $keysValue[$k] = $v[$keys];
	    }
	    $type == SORT_ASC ? asort($keysValue) : arsort($keysValue);
	    reset($keysValue);
	    foreach ($keysValue as $k => $v) {
	        array_push($newArray, $array[$k]);
	    }
	    return $newArray;
	}
	
	
	
}